package com.tvsinfo.jdk.demo.case7_parallel;

import java.util.Spliterator;
import java.util.function.Consumer;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;

/**
 * 自定义的Spliterator
 *
 * @Author ruyi.song
 * @Date 2019/12/30 14:53:33
 */
public class Parallel4_Spliterator {


    public static void main(String[] args) {
        Parallel4_Spliterator parallel4_cusSpliterator=new Parallel4_Spliterator();
        String mm = "private class CustomerSpliterator implements Spliterator Character";
        Spliterator<Character> customerSpliterator = new CustomerSpliterator(mm);
        Stream<Character> stream = StreamSupport.stream(customerSpliterator, true);
        System.out.println("count:"+parallel4_cusSpliterator.countWords(stream));

//        int dd=1&1&~5;
//        System.out.println(dd);
    }

    private int countWords(Stream<Character> stream) {
        WordCounter wordCounter = stream.reduce(new WordCounter(0, true), WordCounter::accumulate, WordCounter::combine);
        return wordCounter.getCounter();
    }

    class WordCounter {
        private final int counter;
        private final boolean lastSpace;

        public WordCounter(int counter, boolean lastSpace) {
            this.counter = counter;
            this.lastSpace = lastSpace;
        }

        public WordCounter accumulate(Character character) {
            if (Character.isWhitespace(character)) {
                return lastSpace ? this : new WordCounter(counter, true);
            } else {
                return lastSpace ? new WordCounter(counter + 1, false) : this;
            }
        }

        public WordCounter combine(WordCounter wordCounter) {
            return new WordCounter(counter + wordCounter.counter, wordCounter.lastSpace);
        }

        public int getCounter() {
            return counter;
        }
    }

    private static class CustomerSpliterator implements Spliterator<Character> {
        private final String string;
        private int currentChar = 0;
        public CustomerSpliterator(String string) {
            this.string = string;
        }

        @Override
        public boolean tryAdvance(Consumer<? super Character> action) {
            action.accept(string.charAt(currentChar++));
            return currentChar < string.length();
        }

        @Override
        public Spliterator<Character> trySplit() {
            int currentSize = string.length() - currentChar;
            if (currentSize < 10) {
                return null;
            }

            for (int splitPos = currentSize / 2 + currentChar; splitPos < string.length(); splitPos++) {
                if (Character.isWhitespace(string.charAt(splitPos))) {
                    Spliterator<Character> spliterator = new CustomerSpliterator(string.substring(currentChar, splitPos));
                    currentChar = splitPos;
                    return spliterator;
                }
            }
            return null;
        }

        @Override
        public long estimateSize() {
            return string.length() - currentChar;
        }
        @Override
        public int characteristics() {
            return ORDERED + SIZED + SUBSIZED + NONNULL + IMMUTABLE;
        }
    }

}
